declare 关键字
在 TypeScript 中,declare
是一个关键字,用于声明类型信息而无需提供实际的实现。它告诉 TypeScript 编译器:“这个变量、函数、类或模块在别处已经存在,你只需要知道它的类型,不要生成对应的 JavaScript 代码。”
简单来说:declare
是用来“描述”已经存在的东西,而不是“创建”新东西。
主要作用
- 类型声明:为现有的 JavaScript 库或全局变量提供类型信息。
- 不生成 JS 代码:
declare
只存在于编译时,TypeScript 编译后不会生成任何 JavaScript 代码。 - 避免类型错误:让 TS 知道某个变量或函数存在,并有正确的类型,从而获得类型检查和编辑器智能提示。
常见使用场景
1. 声明全局变量(Global Variables)
当你在 HTML 中通过 <script>
引入了一个全局库(如 jQuery 或 window.myGlobalVar
),但 TypeScript 不知道它存在,可以用 declare
告诉它:
// 声明一个全局变量
declare const $: any; // 表示 jQuery 存在
// 或者更精确地:
interface JQuery {
(selector: string): JQuery;
html(html: string): JQuery;
}
declare const $: JQuery;
这样你就可以在 TS 文件中安全地使用 $
而不会报错。
2. 声明模块(.d.ts
文件)
当你使用第三方 JS 库,但没有提供 .d.ts
类型定义文件时,你可以自己写一个声明文件。
例如,有一个库 my-library.js
,你想给它加类型:
// my-library.d.ts
declare module 'my-library' {
export function doSomething(): void;
export const VERSION: string;
}
然后你就可以在 TS 中导入并获得类型提示:
import { doSomething } from 'my-library';
doSomething(); // ✅ 类型安全
3. 扩展全局对象(如 window
)
有时你会往 window
上挂载自定义属性,TS 默认不允许这样做,需要用 declare
扩展:
declare global {
interface Window {
myAppConfig: {
apiUrl: string;
};
}
}
// 现在可以安全地使用
window.myAppConfig = { apiUrl: 'https://api.example.com' };
4. 声明函数或类(通常用于外部环境)
declare function greet(name: string): void;
declare class Person {
name: string;
constructor(name: string);
}
这表示这些函数或类在运行时已经存在(比如由框架提供),你只是告诉 TS 它们的结构。
declare
和普通定义的区别
写法 | 是否生成 JS 代码 | 是否需要实现 |
---|---|---|
const x: number; | ❌ 报错(缺少初始化) | ❌ 不合法 |
const x: number = 10; | ✅ 生成 var x = 10; | ✅ 需要值 |
declare const x: number; | ❌ 不生成代码 | ✅ 运行时必须存在 |
典型文件:.d.ts
TypeScript 使用 .d.ts
文件(Declaration File)来存放纯类型声明。最常见的就是:
node_modules/@types/xxx/
下的类型包- 项目中的
global.d.ts
或env.d.ts
例如:
// global.d.ts
declare const PROD: boolean;
declare const API_URL: string;
然后在其他 .ts
文件中可以直接使用 PROD
,而不需要导入。
总结
关键点 | 说明 |
---|---|
declare | 告诉 TS “这东西存在,请给我类型支持” |
不生成代码 | 只在编译时起作用,不影响运行时 |
用途 | 为 JS 库提供类型、声明全局变量、扩展类型等 |
常见文件 | .d.ts 文件,如 global.d.ts |
最佳实践 | 避免滥用,优先使用已有的 @types 包 |
✅ 正确使用 declare
能极大提升 TypeScript 项目的类型安全性和开发体验。